package staticdemo;

/**
 * 单例模式演示
 * 
 * 单例模式是一种常用的创建型设计模式，
 * 它保证一个类只有一个实例，并提供一个全局访问点。
 * static关键字在实现单例模式中起着关键作用。
 */
public class SingletonDemo {
    
    /**
     * 饿汉式单例 - 线程安全
     * 在类加载时就创建实例，天然是线程安全的
     */
    public static class EagerSingleton {
        static {
            System.out.println("饿汉式单例类被加载");
        };

        {
            System.out.println("饿汉式单例被实例化");
        };
        // 使用static和final确保只有一个实例且不能被修改
        private static final EagerSingleton INSTANCE = new EagerSingleton();
        
        // 私有构造函数，防止外部直接创建实例
        private EagerSingleton() {
            System.out.println("饿汉式单例实例被创建");
        }
        
        // 静态方法提供全局访问点
        public static EagerSingleton getInstance() {
            return INSTANCE;
        }
        
        public void doSomething() {
            System.out.println("饿汉式单例执行某些操作");
        }
    }
    
    /**
     * 懒汉式单例 - 线程不安全版本
     */
    public static class LazySingleton {
        // 使用static声明，但延迟初始化
        private static LazySingleton instance;
        
        private LazySingleton() {
            System.out.println("懒汉式单例实例被创建");
        }
        
        // 第一次调用时才创建实例
        public static LazySingleton getInstance() {
            if (instance == null) {
                instance = new LazySingleton();
            }
            return instance;
        }
        
        public void doSomething() {
            System.out.println("懒汉式单例执行某些操作");
        }
    }
    
    /**
     * 懒汉式单例 - 线程安全版本（同步方法）
     */
    public static class SynchronizedLazySingleton {
        private static SynchronizedLazySingleton instance;
        
        private SynchronizedLazySingleton() {
            System.out.println("同步懒汉式单例实例被创建");
        }
        
        // 使用synchronized确保线程安全，但性能较差
        public static synchronized SynchronizedLazySingleton getInstance() {
            if (instance == null) {
                instance = new SynchronizedLazySingleton();
            }
            return instance;
        }
        
        public void doSomething() {
            System.out.println("同步懒汉式单例执行某些操作");
        }
    }
    
    /**
     * 双重检查锁定单例 - 线程安全且高性能
     */
    public static class DoubleCheckSingleton {
        // volatile确保多线程环境下的可见性
        private static volatile DoubleCheckSingleton instance;
        
        private DoubleCheckSingleton() {
            System.out.println("双重检查单例实例被创建");
        }
        
        public static DoubleCheckSingleton getInstance() {
            // 第一次检查，避免不必要的同步
            if (instance == null) {
                synchronized (DoubleCheckSingleton.class) {
                    // 第二次检查，确保只创建一个实例
                    if (instance == null) {
                        instance = new DoubleCheckSingleton();
                    }
                }
            }
            return instance;
        }
        
        public void doSomething() {
            System.out.println("双重检查单例执行某些操作");
        }
    }
    
    /**
     * 静态内部类单例 - 推荐的实现方式
     * 既保证了线程安全，又避免了同步带来的性能影响
     */
    public static class StaticInnerClassSingleton {
        
        private StaticInnerClassSingleton() {
            System.out.println("静态内部类单例实例被创建");
        }
        
        // 静态内部类
        private static class SingletonHolder {
            // 利用类加载机制保证只创建一个实例
            private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
        }
        
        public static StaticInnerClassSingleton getInstance() {
            // 第一次调用时才会加载SingletonHolder类
            return SingletonHolder.INSTANCE;
        }
        
        public void doSomething() {
            System.out.println("静态内部类单例执行某些操作");
        }
    }
    
    /**
     * 枚举单例 - 最安全的单例实现方式
     */
    public enum EnumSingleton {
        INSTANCE;

        static {
            System.out.println("枚举单例类被加载");
        }

        {
            System.out.println("枚举单例被实例化");
        }

        public void doSomething() {
            System.out.println("枚举单例执行某些操作");
        }
    }
    
    public static void main(String[] args) {
        System.out.println("=== 单例模式演示 ===\n");
        
        System.out.println("1. 饿汉式单例：");
        EagerSingleton eager1 = EagerSingleton.getInstance();
        EagerSingleton eager2 = EagerSingleton.getInstance();
        System.out.println("两次获取的实例是否相同: " + (eager1 == eager2));
        eager1.doSomething();

        System.out.println("\n2. 懒汉式单例：");
        LazySingleton lazy1 = LazySingleton.getInstance();
        LazySingleton lazy2 = LazySingleton.getInstance();
        System.out.println("两次获取的实例是否相同: " + (lazy1 == lazy2));
        lazy1.doSomething();
        
        System.out.println("\n3. 同步懒汉式单例：");
        SynchronizedLazySingleton syncLazy1 = SynchronizedLazySingleton.getInstance();
        SynchronizedLazySingleton syncLazy2 = SynchronizedLazySingleton.getInstance();
        System.out.println("两次获取的实例是否相同: " + (syncLazy1 == syncLazy2));
        syncLazy1.doSomething();
        
        System.out.println("\n4. 双重检查单例：");
        DoubleCheckSingleton doubleCheck1 = DoubleCheckSingleton.getInstance();
        DoubleCheckSingleton doubleCheck2 = DoubleCheckSingleton.getInstance();
        System.out.println("两次获取的实例是否相同: " + (doubleCheck1 == doubleCheck2));
        doubleCheck1.doSomething();
        
        System.out.println("\n5. 静态内部类单例：");
        StaticInnerClassSingleton staticInner1 = StaticInnerClassSingleton.getInstance();
        StaticInnerClassSingleton staticInner2 = StaticInnerClassSingleton.getInstance();
        System.out.println("两次获取的实例是否相同: " + (staticInner1 == staticInner2));
        staticInner1.doSomething();
        
        System.out.println("\n6. 枚举单例：");
        EnumSingleton enum1 = EnumSingleton.INSTANCE;
        EnumSingleton enum2 = EnumSingleton.INSTANCE;
        EnumTest enumTest1 = EnumTest.ONE;
        EnumTest enumTest11 = EnumTest.ONE;
        System.out.println("两次获取的实例是否相同: " + (enum1 == enum2));
        System.out.println("两次获取的枚举实例是否相同: " + (enumTest1 == enumTest11));
        enum1.doSomething();
        
        System.out.println("\n=== 各种单例模式比较 ===");
        System.out.println("1. 饿汉式：");
        System.out.println("   - 优点：实现简单，线程安全");
        System.out.println("   - 缺点：类加载时就创建实例，可能造成资源浪费");
        
        System.out.println("\n2. 懒汉式：");
        System.out.println("   - 优点：延迟初始化，节省资源");
        System.out.println("   - 缺点：线程不安全（非同步版本）或性能较差（同步版本）");
        
        System.out.println("\n3. 双重检查锁定：");
        System.out.println("   - 优点：线程安全，性能好");
        System.out.println("   - 缺点：实现复杂，需要volatile关键字");
        
        System.out.println("\n4. 静态内部类：");
        System.out.println("   - 优点：线程安全，性能好，实现简单");
        System.out.println("   - 缺点：无明显缺点，推荐使用");
        
        System.out.println("\n5. 枚举：");
        System.out.println("   - 优点：最安全，防止反射攻击和序列化问题");
        System.out.println("   - 缺点：不够灵活，枚举实例在编译时就确定");
    }
}